package com.shop.cereshop.commons.tencent.im.utils;

import java.math.BigDecimal;
import java.math.RoundingMode;

/**
 * @description: 算术工具类
 * @author zdd
 * @date 2025/9/4 11:33
 * @version 1.0
 */
public class ArithmeticUtils {

    /** 元转分系数（1元 = 100分） */
    private static final BigDecimal YUAN_TO_FEN_RATIO = new BigDecimal("100");
    /** 分转元系数（1分 = 0.01元） */
    private static final BigDecimal FEN_TO_YUAN_RATIO = new BigDecimal("100");
    /** 货币金额默认保留小数位（金融场景标准：2位） */
    private static final int DEFAULT_CURRENCY_SCALE = 2;
    /** 统一舍入模式（四舍五入：符合日常货币计算习惯） */
    private static final RoundingMode DEFAULT_ROUNDING_MODE = RoundingMode.HALF_UP;

    /**
     * 金额：元转换为分
     * @param yuanAmount 元金额（支持任意小数位，超出2位将按四舍五入处理）
     * @return 分金额（Long类型，避免int溢出；入参为null时返回0）
     */
    public static Long yuanToFen(BigDecimal yuanAmount) {
        // 空值安全处理：入参为null时返回0分，避免NullPointerException
        if (yuanAmount == null) {
            return 0L;
        }
        try {
            // 精度预处理：先四舍五入保留2位小数，确保符合货币最小单位（分）的精度要求
            BigDecimal scaledYuan = yuanAmount.setScale(DEFAULT_CURRENCY_SCALE, DEFAULT_ROUNDING_MODE);
            // 单位转换：元 → 分，转换后无小数位（无需担心截断）
            BigDecimal fenAmount = scaledYuan.multiply(YUAN_TO_FEN_RATIO);
            // 类型转换：BigDecimal → Long，避免int类型的溢出风险（如金额超过214748.36元时int会溢出）
            return fenAmount.longValue();
        } catch (ArithmeticException e) {
            // 异常防护：理论上setScale+multiply不会触发算术异常，此处为兜底处理，避免极端场景崩溃
            throw new IllegalArgumentException("元转分计算异常，输入金额：" + yuanAmount, e);
        }
    }

    /**
     * 金额：分转换为元
     * @param fenAmount 分金额（整数；支持null，null时返回0.00元）
     * @return 元金额（BigDecimal类型，固定保留2位小数，符合金融展示标准）
     */
    public static BigDecimal fenToYuan(Long fenAmount) {
        // 空值安全处理：入参为null时返回0.00元，避免NullPointerException
        if (fenAmount == null) {
            return BigDecimal.ZERO.setScale(DEFAULT_CURRENCY_SCALE, DEFAULT_ROUNDING_MODE);
        }
        try {
            // 单位转换：分 → 元，指定除法精度和舍入模式，避免除不尽异常（如极端场景下的非法分金额）
            return new BigDecimal(fenAmount)
                    .divide(FEN_TO_YUAN_RATIO, DEFAULT_CURRENCY_SCALE, DEFAULT_ROUNDING_MODE);
        } catch (ArithmeticException e) {
            // 异常防护：兜底处理非法分金额（如分金额为非整数场景），明确异常原因
            throw new IllegalArgumentException("分转元计算异常，输入分金额：" + fenAmount, e);
        }
    }

}
